package com.filetransfer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.filetransfer.dao.DeviceMapper;
import com.filetransfer.model.dto.DeviceDTO;
import com.filetransfer.model.entity.Device;
import com.filetransfer.service.DeviceService;
import com.filetransfer.util.DeviceDiscoveryUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 设备服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceServiceImpl implements DeviceService {

    private final DeviceMapper deviceMapper;
    private final DeviceDiscoveryUtil deviceDiscoveryUtil;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String registerDevice(DeviceDTO deviceDTO) {
        // 查询设备是否已存在
        Device existingDevice = deviceMapper.selectById(deviceDTO.getId());
        
        LocalDateTime now = LocalDateTime.now();
        
        if (existingDevice != null) {
            // 更新设备信息
            Device device = new Device();
            BeanUtils.copyProperties(deviceDTO, device);
            device.setStatus(1); // 在线状态
            device.setLastSeen(now);
            
            deviceMapper.updateById(device);
            return device.getId();
        } else {
            // 创建新设备
            Device device = new Device();
            BeanUtils.copyProperties(deviceDTO, device);
            device.setStatus(1); // 在线状态
            device.setLastSeen(now);
            
            deviceMapper.insert(device);
            return device.getId();
        }
    }
    
    @Override
    public boolean updateDeviceStatus(String deviceId, Integer status) {
        LambdaUpdateWrapper<Device> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Device::getId, deviceId)
                .set(Device::getStatus, status)
                .set(Device::getLastSeen, LocalDateTime.now());
        
        return deviceMapper.update(null, updateWrapper) > 0;
    }
    
    @Override
    public boolean updateDeviceName(String deviceId, String deviceName) {
        LambdaUpdateWrapper<Device> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Device::getId, deviceId)
                .set(Device::getDeviceName, deviceName)
                .set(Device::getLastSeen, LocalDateTime.now());
        
        return deviceMapper.update(null, updateWrapper) > 0;
    }
    
    @Override
    public DeviceDTO getDeviceDetail(String deviceId) {
        Device device = deviceMapper.selectById(deviceId);
        return device != null ? convertToDTO(device) : null;
    }
    
    @Override
    public List<DeviceDTO> getOnlineDevices() {
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Device::getLastSeen);
        
        return deviceMapper.selectList(queryWrapper)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public int discoverDevices() {
        // 调用设备发现工具进行UDP广播
        List<Device> discoveredDevices = deviceDiscoveryUtil.discoverDevices();
        
        int count = 0;
        for (Device device : discoveredDevices) {
            // 检查设备是否已存在
            Device existingDevice = deviceMapper.selectById(device.getId());
            
            if (existingDevice == null) {
                // 新设备，直接插入
                deviceMapper.insert(device);
                count++;
            } else {
                // 更新已有设备的状态和最后在线时间
                LambdaUpdateWrapper<Device> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(Device::getId, device.getId())
                        .set(Device::getStatus, device.getStatus())
                        .set(Device::getIpAddress, device.getIpAddress())
                        .set(Device::getLastSeen, LocalDateTime.now());
                
                deviceMapper.update(null, updateWrapper);
                count++;
            }
        }
        
        return count;
    }
    
    @Override
    public DeviceDTO getDeviceByIp(String ipAddress) {
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getIpAddress, ipAddress);
        
        Device device = deviceMapper.selectOne(queryWrapper);
        return device != null ? convertToDTO(device) : null;
    }
    
    @Override
    public DeviceDTO convertToDTO(Device device) {
        if (device == null) {
            return null;
        }
        
        DeviceDTO deviceDTO = new DeviceDTO();
        BeanUtils.copyProperties(device, deviceDTO);
        return deviceDTO;
    }
} 